package com.myproject.mall.goods.consumer;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.myproject.mall.common.config.RabbitMQConfig;
import com.myproject.mall.domain.entity.Goods;
import com.myproject.mall.domain.entity.Order;
import com.myproject.mall.domain.enums.OrderStatus;
import com.myproject.mall.goods.mapper.GoodsMapper;
import com.myproject.mall.goods.mapper.OrderMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
@RequiredArgsConstructor
public class OrderMessageConsumer {
    private final OrderMapper orderMapper;
    private final GoodsMapper goodsMapper;
    private final RedissonClient redissonClient;
    /**
     * 创建订单
     */
    @RabbitListener(queues = RabbitMQConfig.ORDER_CREATE_QUEUE)
    public void handleOrderCreate(Order order) {
        try {
            log.info("处理订单创建，订单ID：{}", order.getId());
//            TODO 通知商家
            String message = "订单创建成功，订单ID：" + order.getId();
            notifySeller(message);

            log.info("订单创建处理，订单ID：{}", order.getId());

        } catch (Exception e) {
            log.error("处理订单创建异常，订单ID：{}", order.getId(), e);
//            TODO 失败处理
        }
    }

    /**
     * 订单支付
     */
    @RabbitListener(queues = RabbitMQConfig.ORDER_PAY_QUEUE)
    public void payOrder(Order order) {
        log.info("订单支付处理，订单ID：{}", order.getId());
//        TODO 订单支付处理
    }

    /**
     * 订单主动取消
     */
    @Transactional
    @RabbitListener(queues = RabbitMQConfig.ORDER_CANCEL_QUEUE)
    public void handleOrderCancel(Order order) {
        log.info("订单取消处理，订单ID：{}，消费者ID：{}", order.getId(), order.getBuyerId());

        try {
            cancelOrder(order);
            log.info("订单取消完成，订单ID：{}", order.getId());
//            TODO 通知用户
        } catch (Exception e) {
            log.error("处理订单取消异常，订单ID：{}", order.getId(), e);
        }
    }

    /**
     * 超时取消
     */
    @Transactional
    @RabbitListener(queues = RabbitMQConfig.ORDER_TIMEOUT_QUEUE)
    public void handleOrderTimeout(Long orderId) {
        log.info("开始检验订单超时，订单ID：{}", orderId);

        Order order = orderMapper.selectById(orderId);

        if(order != null && order.getStatus() == OrderStatus.UNPAID) {
            try{
                cancelOrder(order);
                log.info("订单因超时取消成功，订单ID：{}", orderId);
//                TODO 通知用户订单已经超时取消
            }
            catch (Exception e) {
                log.error("订单因超时取消异常，订单ID：{}", orderId, e);
            }
        }
        else {
            log.info("订单已被用户处理，无需超时处理，订单ID：{}", orderId);
        }
    }

    /**
     * 接收所有时间，日志监控
     */
    @RabbitListener(queues = RabbitMQConfig.ORDER_ALL_QUEUE)
    public void handleOrderAll(Order order) {
        log.info("处理所有订单，订单ID：{}，订单状态：{}", order.getId(), order.getStatus());
    }

    private void notifySeller(String message) {
        log.info("通知卖家，消息：{}", message);
//        TODO 通知卖家
    }

    private void cancelOrder(Order order) {
        RLock lock = redissonClient.getLock("order:cancel:" + order.getId());
        if(lock.tryLock()) {
            try{
                orderMapper.update(new LambdaUpdateWrapper<Order>()
                        .eq(Order::getId, order.getId())
                        .set(Order::getStatus, OrderStatus.CANCELED)
                );
                goodsMapper.update(new LambdaUpdateWrapper<Goods>()
                        .eq(Goods::getId, order.getGoodsId())
                        .setSql("goods_amount = goods_amount + #{order.amount}", order)
                );
            }
            catch (Exception e) {
                log.error("订单取消异常，订单ID：{}", order.getId(), e);
            }
            finally {
                lock.unlock();
            }
        }
    }

}
